package cn.nexd.map.coreLocator;

import org.json.JSONException;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

/**
 * Created by admin on 15/9/23.
 */
public class coreFloorDetection {
    private Map<String, Double[]> mean = new HashMap<>();
    private Map<String, Double[]> var = new HashMap<>();
    private Map<String, Double[]> weight = new HashMap<>();
    public String[] wifilist;

    private Map<String, String> floorRef = new Hashtable<>();

    public String floorDetection(String wifi, coreWifiExtractor cw) throws JSONException {
        Double[] vec = cw.extractWifiWithRef(wifi, wifilist);
        Double prob_max = -10000.0;
        String floor = "";
        for (String flr : mean.keySet()) {
            Double prob = getFloorProbability(vec, flr);
            //            System.out.printf("Floor %s with the probability : %f\n", flr, prob);
            if (prob > prob_max) {
                prob_max = prob;
                floor = flr;
            }
            //            Log.d("FloorDetection", flr + " : " + prob.toString());
        }

        //        Log.d("FloorDetectionResult",floor);
        //        return floorRef.get(floor);
        return floor;
    }

    //    public String floorDetection(Double[] vec) throws JSONException {
    //        Double prob_max = -10000.0;
    //        String floor = "";
    //        for(String flr : mean.keySet()){
    //            Double prob = getFloorProbability(vec, flr);
    ////            System.out.printf("Floor %s with the probability : %f\n", flr, prob);
    //            if (prob > prob_max){
    //                prob_max = prob;
    //                floor = flr;
    //            }
    //        }
    //        return floorRef.get(floor);
    //    }

    private Double getFloorProbability(Double[] vec, String key) {
        Double sum = 0.0;
        Double[] t_mean = mean.get(key);
        Double[] t_var = var.get(key);
        Double[] t_weight = weight.get(key);
        for (int i = 0, len = vec.length; i < len; i++) {
            if (vec[i] > 1e-3) {
                sum += Math.exp(-Math.pow(vec[i] - t_mean[i], 2) / 2.0 / t_var[i] / t_var[i]) / t_var[i] * t_weight[i];
                //                sum += Math.exp(-Math.pow(vec[i] - t_mean[i], 2) / 2.0 / t_var[i] / t_var[i]) / t_var[i];
            }
        }
        return sum;
    }


    public void loadConfiguration(InputStream mean, InputStream var, InputStream weight, InputStream wifilist) throws IOException {
        _loadMean(mean);
        _loadVar(var);
        _loadWeight(weight);
        _loadWifilist(wifilist);
        //        floorRef.put("EF2", "LenovoBeiYan__EF2");
        //        floorRef.put("EF3", "LenovoBeiYan__EF3");
        //        floorRef.put("EF4", "LenovoBeiYan__EF4");
        //        floorRef.put("EF5", "LenovoBeiYan__EF5");
        //        floorRef.put("EF6", "LenovoBeiYan__EF6");
        //        floorRef.put("EF7", "LenovoBeiYan__EF7");
        //        floorRef.put("EF8", "LenovoBeiYan__EF8");
        //        floorRef.put("F1", "YouTang___F1");
        //        floorRef.put("F2", "YouTang___F2");
        //        floorRef.put("F3", "YouTang___F3");
        //        floorRef.put("F4", "YouTang___F4");
        //        floorRef.put("F5", "YouTang___F5");
        //        floorRef.put("B1", "YouTang___B1");
    }

    public void checkLoading() {
        for (String v : mean.keySet()) {
            System.out.println(v);
            for (int i = 0, len = mean.get(v).length; i < len; i++) {
                System.out.println(mean.get(v)[i]);
            }
        }

    }

    private void _loadWifilist(InputStream inputStream) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        try {
            String line = bufferedReader.readLine();
            if (line != null) {
                wifilist = line.split(",");
            }
        } finally {
            bufferedReader.close();
        }
    }

    private void _loadMean(InputStream inputStream) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        try {
            String line = bufferedReader.readLine();

            while (line != null) {
                String[] linesplit = line.split(":");
                String[] value = linesplit[1].split(",");
                Double[] digitValue = new Double[value.length];
                for (int i = 0; i < value.length; i++) {
                    digitValue[i] = Double.parseDouble(value[i]);
                }
                mean.put(linesplit[0], digitValue);
                line = bufferedReader.readLine();
            }
        } finally {
            bufferedReader.close();
        }
    }

    private void _loadVar(InputStream inputStream) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        try {
            String line = bufferedReader.readLine();

            while (line != null) {
                String[] linesplit = line.split(":");
                String[] value = linesplit[1].split(",");
                Double[] digitValue = new Double[value.length];
                for (int i = 0; i < value.length; i++) {
                    digitValue[i] = Double.parseDouble(value[i]);
                }
                var.put(linesplit[0], digitValue);
                line = bufferedReader.readLine();
            }
        } finally {
            bufferedReader.close();
        }
    }


    private void _loadWeight(InputStream inputStream) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        try {
            String line = bufferedReader.readLine();

            while (line != null) {
                String[] linesplit = line.split(":");
                String[] value = linesplit[1].split(",");
                Double[] digitValue = new Double[value.length];
                for (int i = 0; i < value.length; i++) {
                    digitValue[i] = Double.parseDouble(value[i]);
                }
                weight.put(linesplit[0], digitValue);
                line = bufferedReader.readLine();
            }
        } finally {
            bufferedReader.close();
        }
    }


}
